﻿using Cdy.Tag;
using DBDevelopClientWebApi;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace MarsUniformApi
{

    public class MarsApi:INotifyPropertyChanged,IDisposable
    {
        private DBHighApi.HighSpeedApiClient mHightClient;
        private DirectAccessDriver.ClientApi.DirectAccessClient mDriverClient;
        private DBDevelopClientWebApi.WebDevelopApiClient mWebDevelopClient;

        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// 
        /// </summary>
        public MarsApi()
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="username"></param>
        /// <param name="pass"></param>
        /// <param name="collectorPort"></param>
        /// <param name="comsumerPort"></param>
        /// <param name="managerPort"></param>
        public MarsApi(string ip, string username, string pass,int collectorPort,int comsumerPort,int managerPort) : this(new ServerParameter() { Ip = ip, Port = comsumerPort, Password = pass, UserName = username }, new ServerParameter() { Ip = ip, Port = collectorPort, Password = pass, UserName = username }, new ServerParameter() { Ip = ip, Port = managerPort, Password = pass, UserName = username })
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="username"></param>
        /// <param name="pass"></param>
        public MarsApi(string ip,string username,string pass):this(new ServerParameter() { Ip=ip,Port= 14332, Password=pass,UserName=username}, new ServerParameter() { Ip = ip, Port = 9800, Password = pass, UserName = username }, new ServerParameter() { Ip = ip, Port = 9000, Password = pass, UserName = username })
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mHighParameter"></param>
        /// <param name="mDriverClientParameter"></param>
        /// <param name="webDevelopClient"></param>
        public MarsApi(ServerParameter mHighParameter, ServerParameter mDriverClientParameter, ServerParameter webDevelopClient)
        {
            mHightClient = new DBHighApi.HighSpeedApiClient() { ServerIp = mHighParameter.Ip,Port = mHighParameter.Port,UserName=mHighParameter.UserName,Password=mHighParameter.Password};
            mDriverClient = new DirectAccessDriver.ClientApi.DirectAccessClient() { ServerIp = mDriverClientParameter.Ip,Port = mDriverClientParameter.Port,UserName=mDriverClientParameter.UserName,Password=mDriverClientParameter.Password};
            mWebDevelopClient = new DBDevelopClientWebApi.WebDevelopApiClient() { Server = "http://"+ webDevelopClient.Ip + ":" + webDevelopClient.Port,UserName=webDevelopClient.UserName,Password=webDevelopClient.Password };
        }

        /// <summary>
        /// 使能业务端API
        /// </summary>
        /// <param name="value"></param>
        /// <param name="ip"></param>
        /// <param name="username"></param>
        /// <param name="pass"></param>
        /// <param name="port"></param>
        public void EnableComsumer(bool value,string ip,string username,string pass,int port = 14332)
        {
            if(value)
            {
                if(mHightClient != null)
                {
                    mHightClient.Close();
                    mHightClient.ServerIp = ip;
                    mHightClient.Port = port;
                    mHightClient.UserName = username; 
                    mHightClient.Password = pass;
                }
                else
                {
                    mHightClient = new DBHighApi.HighSpeedApiClient() { ServerIp = ip, Port = port, UserName = username, Password = pass};
                }
            }
            else
            {
                if(mHightClient != null)
                {
                    mHightClient.Close();
                    mHightClient.Dispose();
                    mHightClient=null;
                }
            }
        }

        /// <summary>
        /// 使能采集端API
        /// </summary>
        /// <param name="value"></param>
        /// <param name="ip"></param>
        /// <param name="username"></param>
        /// <param name="pass"></param>
        /// <param name="port"></param>
        public void EnableCollector(bool value, string ip, string username, string pass, int port= 9800)
        {
            if (value)
            {
                if (mDriverClient != null)
                {
                    mDriverClient.Close();
                    mDriverClient.ServerIp = ip;
                    mDriverClient.Port = port;
                    mDriverClient.UserName = username;
                    mDriverClient.Password = pass;
                }
                else
                {
                    mDriverClient = new DirectAccessDriver.ClientApi.DirectAccessClient() { ServerIp = ip, Port = port, UserName = username, Password = pass };
                }
            }
            else
            {
                if (mDriverClient != null)
                {
                    mDriverClient.Close();
                    mDriverClient.Dispose();
                    mDriverClient = null;
                }
            }
        }

        /// <summary>
        /// 使能管理端API
        /// </summary>
        /// <param name="value"></param>
        /// <param name="ip"></param>
        /// <param name="username"></param>
        /// <param name="pass"></param>
        /// <param name="port"></param>
        public void EnableManager(bool value, string ip, string username, string pass, int port= 9000)
        {
            if (value)
            {
                if (mWebDevelopClient != null)
                {
                    mWebDevelopClient.Logout();
                    mWebDevelopClient.Server = "http://" + ip + ":" + port;
                    mWebDevelopClient.UserName = username;
                    mWebDevelopClient.Password = pass;
                }
                else
                {
                    mWebDevelopClient = new DBDevelopClientWebApi.WebDevelopApiClient() { Server = "http://" + ip + ":" + port, UserName = username, Password = pass };
                }
            }
            else
            {
                if (mWebDevelopClient != null)
                {
                    mWebDevelopClient.Logout();
                    mWebDevelopClient.Dispose();
                    mWebDevelopClient = null;
                }
            }
        }

        /// <summary>
        /// 连接服务器
        /// <paramref name="timeout">通信超时</paramref>
        /// </summary>
        public void Connect(int timeout = 10000)
        {
            if (mHightClient != null)
            {
                mHightClient.PropertyChanged += MHightClient_PropertyChanged;
                mHightClient.Open();
            }
            if (mDriverClient != null)
            {
                mDriverClient.PropertyChanged += MHightClient_PropertyChanged;
                mDriverClient.Open();
            }
            if (mWebDevelopClient != null)
                mWebDevelopClient.Timeout = timeout;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MHightClient_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            OnPropertyChanged(e.PropertyName);
        }

        /// <summary>
        /// 登录
        /// <paramref name="timeout">登录超时</paramref>
        /// </summary>
        public void Login(int timeout=10000)
        {
            mHightClient?.Login(timeout);
            mDriverClient?.Login(timeout);
            mWebDevelopClient?.Login();
        }

        /// <summary>
        /// 退出登录
        /// </summary>
        public void Logout()
        {
            mHightClient?.Close();
            mDriverClient?.Close();
            mWebDevelopClient?.Logout();
        }

        /// <summary>
        /// 是否全部登录
        /// </summary>
        /// <returns></returns>
        public bool IsLogin()
        {
            bool re = true;
            if(mHightClient != null)
            {
                re &= mHightClient.IsLogin;
            }
            if (mDriverClient != null)
            {
                re &= mDriverClient.IsLogin;
            }
            if (mWebDevelopClient != null)
            {
                re &= mWebDevelopClient.IsLogin;
            }
            return re;
        }

        /// <summary>
        /// 采集器是否登录
        /// </summary>
        /// <returns></returns>
        public bool IsCollectorLogin()
        {
            return mDriverClient != null ? mDriverClient.IsLogin : false;
        }

        /// <summary>
        /// 业务API是否登录成功
        /// </summary>
        /// <returns></returns>
        public bool IsConsumerLogin()
        {
            return mHightClient != null ? mHightClient.IsLogin : false;
        }

        /// <summary>
        /// 管理API登录成功
        /// </summary>
        /// <returns></returns>
        public bool IsManagerLogin()
        {
            return mWebDevelopClient != null ? mWebDevelopClient.IsLogin : false;
        }

        /// <summary>
        /// 是否建立连接
        /// </summary>
        /// <returns></returns>
        public bool IsConnected()
        {
            bool re = true;
            if (mHightClient != null)
            {
                re &= mHightClient.IsConnected;
            }
            if (mDriverClient != null)
            {
                re &= mDriverClient.IsConnected;
            }
            return re;
        }

        /// <summary>
        /// 采集器是否连接成功
        /// </summary>
        /// <returns></returns>
        public bool IsCollectorConnected()
        {
            return mDriverClient != null ? mDriverClient.IsConnected : false;
        }

        /// <summary>
        /// 业务API是否连接成功
        /// </summary>
        /// <returns></returns>
        public bool IsConsumerConnected()
        {
            return mHightClient != null ? mHightClient.IsConnected : false;
        }

        #region Consumer HighSpeed Api

        /// <summary>
        /// 业务端 设置值改变主动推动回调函数
        /// </summary>
        /// <param name="callback"></param>
        public void SetTagValueChangedCallBackForConsumer(DBHighApi.HighSpeedApiClient.TagValueChangedCallBackDelegate callback)
        {
            mHightClient.TagValueChangedCallBack = callback;
        }

        /// <summary>
        /// 业务端运行时 根据变量名称获取变量的ID
        /// </summary>
        /// <param name="tagNames">变量名集合</param>
        /// <param name="timeout">超时</param>
        /// <returns>变量名称、Id</returns>
        public Dictionary<string, int> GetTagIdsForConsumer(List<string> tagNames, int timeout = 5000)
        {
            return mHightClient.GetTagIds(tagNames, timeout);
        }

        /// <summary>
        /// 业务端运行时 枚举所有变量
        /// </summary>
        /// <param name="timeout">超时</param>
        /// <returns></returns>
        public Dictionary<string, int> ListAllTagForConsumer(int timeout = 30000)
        {
           return mHightClient.ListAllTag(timeout);
        }

        /// <summary>
        /// 从业务端运行时 枚举所有变量组
        /// </summary>
        /// <param name="timeout">超时</param>
        /// <returns></returns>
        public List<string> ListALlTagGroupForConsumer(int timeout = 30000)
        {
            return mHightClient.ListALlTagGroup();
        }

        /// <summary>
        /// 从业务端运行时 获取某个变量组下的变量
        /// </summary>
        /// <param name="group">组</param>
        /// <param name="timeout">超时 </param>
        /// <returns></returns>
        public Dictionary<string, int> ListTagByGroupForConsumer(string group, int timeout = 30000)
        {
           return mHightClient.ListTagByGroup(group, timeout);
        }

        /// <summary>
        /// 从业务端运行时 获取当前运行的数据的名称
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public string GetRunnerDatabaseForConsumer(int timeout = 5000)
        {
            return mHightClient.GetRunnerDatabase(timeout);

        }

        #region RealData

        /// <summary>
        /// 从业务端订购变量值改变通知
        /// </summary>
        /// <param name="minid">变量ID最小值</param>
        /// <param name="maxid">变量ID最大值</param>
        /// <param name="timeout">超时</param>
        /// <returns></returns>
        public bool RegistorTagValueCallBack(int minid, int maxid, int timeout = 5000)
        {
            return mHightClient.RegistorTagValueCallBack(minid, maxid, timeout);
        }

        /// <summary>
        /// 从业务端订购变量值改变通知
        /// </summary>
        /// <param name="ids">变量ID集合</param>
        /// <param name="timeout">超时</param>
        /// <returns></returns>
        public bool RegistorTagValueCallBack(List<int> ids, int timeout = 5000)
        {
            return mHightClient.RegistorTagValueCallBack(ids, timeout);
        }

        /// <summary>
        /// 从业务端清除变量值改变通知
        /// </summary>
        /// <param name="timeout">超时</param>
        /// <returns></returns>
        public bool ClearRegistorTagValueCallBack(int timeout = 5000)
        {
            return mHightClient.ClearRegistorTagValueCallBack(timeout);
        }


        /// <summary>
        /// 从业务端清除变量值改变通知
        /// </summary>
        /// <param name="ids">ID集合</param>
        /// <param name="timeout">超时</param>
        /// <returns></returns>
        public bool ClearRegistorTagValueCallBack(List<int> ids,int timeout = 5000)
        {
            return mHightClient.ClearRegistorTagValueCallBack(ids,timeout);
        }


        /// <summary>
        /// 从业务端获取变量实时值
        /// </summary>
        /// <param name="ids">变量Id集合</param>
        /// <param name="nocache">是否从缓存中读取，从缓冲中读取会提高访问速度，但是数值本身会有一定的滞后</param>
        /// <param name="timeout">超时缺省:5000</param>
        /// <returns>变量Id，值，时间,质量 的集合</returns>
        public Dictionary<int, Tuple<object, DateTime, byte>> GetRealDataForConsumer(List<int> ids, bool nocache = false, int timeout = 5000)
        {
            return mHightClient.GetRealData(ids, nocache, timeout);
        }

        /// <summary>
        /// 从业务端获取变量实时值
        /// </summary>
        /// <param name="ids">变量Id集合</param>
        /// <param name="nocache">是否从缓存中读取，从缓冲中读取会提高访问速度，但是数值本身会有一定的滞后</param>
        /// <param name="timeout">超时缺省:5000</param>
        /// <returns>变量Id，值</returns>
        public Dictionary<int, object> GetRealDataValueOnlyForConsumer(List<int> ids, bool nocache = false, int timeout = 5000)
        {
            return mHightClient.GetRealDataValueOnly(ids, nocache, timeout);
        }

        /// <summary>
        /// 从业务端获取变量实时值、质量戳
        /// </summary>
        /// <param name="ids">变量Id集合</param>
        /// <param name="nocache">是否从缓存中读取，从缓冲中读取会提高访问速度，但是数值本身会有一定的滞后</param>
        /// <param name="timeout">超时缺省:5000</param>
        /// <returns>变量Id，值，质量 的集合</returns>
        public Dictionary<int, Tuple<object, byte>> GetRealDataValueAndQualityOnlyForConsumer(List<int> ids, bool nocache = false, int timeout = 5000)
        {
            return mHightClient.GetRealDataValueAndQualityOnly(ids, nocache, timeout);
        }

        /// <summary>
        /// 从业务端获取变量实时值，通过指定变量ID范围
        /// </summary>
        /// <param name="startId">开始变量的ID</param>
        /// <param name="endId">结束变量的ID</param>
        /// <param name="nocache">是否从缓存中读取，从缓冲中读取会提高访问速度，但是数值本身会有一定的滞后</param>
        /// <param name="timeout">超时缺省:5000</param>
        /// <returns>变量Id，值，时间,质量 的集合</returns>
        public Dictionary<int, Tuple<object, DateTime, byte>> GetRealDataForConsumer(int startId, int endId, bool nocache = false, int timeout = 5000)
        {
            return mHightClient.GetRealData(startId,endId,nocache,timeout);
        }

        /// <summary>
        /// 从业务端获取变量实时值，通过指定变量ID范围
        /// </summary>
        /// <param name="startId">开始变量的ID</param>
        /// <param name="endId">结束变量的ID</param>
        /// <param name="nocache">是否从缓存中读取，从缓冲中读取会提高访问速度，但是数值本身会有一定的滞后</param>
        /// <param name="timeout">超时缺省:5000</param>
        /// <returns>变量Id，值</returns>
        public Dictionary<int, object> GetRealDataValueOnlyForConsumer(int startId, int endId, bool nocache = false, int timeout = 5000)
        {
           return mHightClient.GetRealDataValueOnly(startId,endId,nocache,timeout);
        }

        /// <summary>
        /// 从业务端获取变量实时值，通过指定变量ID范围
        /// </summary>
        /// <param name="startId">开始变量的ID</param>
        /// <param name="endId">结束变量的ID</param>
        /// <param name="nocache">是否从缓存中读取，从缓冲中读取会提高访问速度，但是数值本身会有一定的滞后</param>
        /// <param name="timeout">超时缺省:5000</param>
        /// <returns>变量Id，值,质量 的集合</returns>

        public Dictionary<int, Tuple<object, byte>> GetRealDataValueAndQualityOnlyForConsumer(int startId, int endId, bool nocache = false, int timeout = 5000)
        {
            return mHightClient.GetRealDataValueAndQualityOnly(startId,endId,nocache,timeout);
        }


        /// <summary>
        /// 从业务端设置变量的值
        /// </summary>
        /// <param name="id">变量Id</param>
        /// <param name="valueType">值类型<see cref="Cdy.Tag.TagType"/></param>
        /// <param name="value">值</param>
        /// <param name="timeout">超时 缺省:5000 ms</param>
        public bool SetTagValueForConsumer(int id, byte valueType, object value, int timeout = 5000)
        {
            return mHightClient.SetTagValue(id, valueType, value, timeout);
        }

        /// <summary>
        /// 从业务端设置一组变量的值
        /// </summary>
        /// <param name="id">变量ID集合</param>
        /// <param name="valueType">值类型集合</param>
        /// <param name="value">值集合</param>
        /// <param name="timeout">超时 缺省:5000 ms</param>
        /// <returns></returns>
        public bool SetTagValueForConsumer(List<int> id, List<byte> valueType, List<object> value, int timeout = 5000)
        {
            return mHightClient.SetTagValue(id,valueType,value,timeout);
        }


        ///// <summary>
        ///// 从业务端设置变量的值修改成上一次变更的有效值
        ///// </summary>
        ///// <param name="id">变量Id</param>
        ///// <param name="timeout">超时 缺省:5000 ms</param>
        //public bool SetTagValueToLastValueForConsumer(int id, byte valueType, object value, int timeout = 5000)
        //{
        //    return mHightClient.SetTagValueToLastValue(id,valueType,value,timeout);
        //}


        #endregion


        #region HisData

        /// <summary>
        /// 查询某个变量的某个时间段内的记录的所有值
        /// </summary>
        /// <param name="id">Id</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="timeout">超时 缺省:5000 ms</param>
        /// <returns></returns>
        public Cdy.Tag.HisQueryResult<T> QueryAllHisValue<T>(int id, DateTime startTime, DateTime endTime, int timeout = 5000)
        {
           return mHightClient.QueryAllHisValue<T>(id, startTime, endTime, timeout);
        }

        /// <summary>
        /// 查询某个变量在一系列时间点上得值
        /// </summary>
        /// <param name="id">变量Id</param>
        /// <param name="times">时间点集合</param>
        /// <param name="matchType">值拟合类型<see cref="Cdy.Tag.QueryValueMatchType"/></param>
        /// <param name="timeout">超时 缺省:5000 ms</param>
        /// <returns></returns>
        public Cdy.Tag.HisQueryResult<T> QueryHisValueAtTimes<T>(int id, List<DateTime> times, Cdy.Tag.QueryValueMatchType matchType, int timeout = 5000)
        {
           return mHightClient.QueryHisValueAtTimes<T>(id, times, matchType, timeout);
        }

        /// <summary>
        /// 查询某个变量在一系列时间点上得值,忽略系统退出对数据的影响
        /// </summary>
        /// <param name="id">变量Id</param>
        /// <param name="times">时间点集合</param>
        /// <param name="matchType">值拟合类型<see cref="Cdy.Tag.QueryValueMatchType"/></param>
        /// <param name="timeout">超时 缺省:5000 ms</param>
        /// <returns></returns>
        public Cdy.Tag.HisQueryResult<T> QueryHisValueAtTimesByIgnorSystemExit<T>(int id, List<DateTime> times, Cdy.Tag.QueryValueMatchType matchType, int timeout = 5000)
        {
            return mHightClient.QueryHisValueAtTimesByIgnorSystemExit<T>(id, times, matchType, timeout);
        }

        /// <summary>
        /// 查询某个变量在一系列时间点上得值,通过指定时间间隔确定时间点
        /// </summary>
        /// <param name="id">变量Id</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="span">时间间隔<see cref="System.TimeSpan"/></param>
        /// <param name="matchType">值拟合类型<see cref="Cdy.Tag.QueryValueMatchType"/></param>
        /// <param name="timeout">超时 缺省:5000ms</param>
        /// <returns></returns>
        public Cdy.Tag.HisQueryResult<T> QueryHisValueForTimeSpan<T>(int id, DateTime startTime, DateTime endTime, TimeSpan span, Cdy.Tag.QueryValueMatchType matchType, int timeout = 5000)
        {
           return mHightClient.QueryHisValueForTimeSpan<T>(id, startTime, endTime, span, matchType, timeout);
        }

        /// <summary>
        /// 查询某个变量在一系列时间点上得值,通过指定时间间隔确定时间点,忽略系统退出对数据的影响
        /// </summary>
        /// <param name="id">变量Id</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="span">时间间隔<see cref="System.TimeSpan"/></param>
        /// <param name="matchType">值拟合类型<see cref="Cdy.Tag.QueryValueMatchType"/></param>
        /// <param name="timeout">超时 缺省:5000ms</param>
        /// <returns></returns>
        public Cdy.Tag.HisQueryResult<T> QueryHisValueForTimeSpanByIgnorSystemExit<T>(int id, DateTime startTime, DateTime endTime, TimeSpan span, Cdy.Tag.QueryValueMatchType matchType, int timeout = 5000)
        {
            return mHightClient.QueryHisValueForTimeSpanByIgnorSystemExit<T>(id, startTime, endTime, span, matchType, timeout);
        }



        /// <summary>
        /// 查询某个变量某个时间段内的记录的统计值
        /// </summary>
        /// <param name="id">变量Id</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="timeout">超时 缺省:5000ms</param>
        /// <returns></returns>
        public Cdy.Tag.NumberStatisticsQueryResult QueryStatisticsValue(int id, DateTime startTime, DateTime endTime, int timeout = 5000)
        {
            return mHightClient.QueryStatisticsValue(id, startTime, endTime, timeout);
        }

        /// <summary>
        /// 查询某个变量在某个时刻上的记录的统计值
        /// </summary>
        /// <param name="id">变量Id</param>
        /// <param name="times">时间集合</param>
        /// <param name="timeout">超时 缺省:5000ms</param>
        /// <returns></returns>
        public Cdy.Tag.NumberStatisticsQueryResult QueryStatisticsAtTimes(int id, List<DateTime> times, int timeout = 5000)
        {
            return mHightClient.QueryStatisticsAtTimes(id, times, timeout);
        }



        /// <summary>
        /// 查找某个值对应的时间
        /// </summary>
        /// <param name="id">变量的Id</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="type">值比较类型 <see cref="Cdy.Tag.NumberStatisticsType"/></param>
        /// <param name="value">值</param>
        /// <param name="timeout">超时 缺省:30000</param>
        /// <returns></returns>
        public Tuple<DateTime, object> FindTagValue(int id, DateTime startTime, DateTime endTime, Cdy.Tag.NumberStatisticsType type, object value, int timeout = 30000)
        {
           return mHightClient.FindTagValue(id, startTime, endTime, type, value, timeout);
        }

        /// <summary>
        /// 查找某个值保持的时间
        /// </summary>
        /// <param name="tag">变量的Id</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="type">值比较类型 <see cref="Cdy.Tag.NumberStatisticsType"/></param>
        /// <param name="value">值</param>
        /// <param name="timeout">超时 缺省:30000</param>
        /// <returns></returns>
        public double? CalTagValueKeepTime(int tag, DateTime startTime, DateTime endTime, Cdy.Tag.NumberStatisticsType type, object value, int timeout = 30000)
        {
            return mHightClient.CalTagValueKeepTime(tag, startTime, endTime, type, value, timeout);
        }

        /// <summary>
        /// 查找某个值对应的时间
        /// </summary>
        /// <param name="tag">变量的Id</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="type">值比较类型 <see cref="Cdy.Tag.NumberStatisticsType"/></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public Dictionary<DateTime, object> FindTagValues(int tag, DateTime startTime, DateTime endTime, Cdy.Tag.NumberStatisticsType type, object value, double interval, int timeout)
        {
            return mHightClient.FindTagValues(tag, startTime, endTime, type, value, interval, timeout);
        }

        /// <summary>
        /// 查找最大值
        /// </summary>
        /// <param name="tag">变量的Id</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public Tuple<double, List<DateTime>> FindNumberTagMaxValue(int tag, DateTime startTime, DateTime endTime, int timeout = 30000)
        {
            return mHightClient.FindNumberTagMaxValue(tag, startTime, endTime, timeout);
        }

        /// <summary>
        /// 查找最小值
        /// </summary>
        /// <param name="tag">变量的Id</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public Tuple<double, List<DateTime>> FindNumberTagMinValue(int tag, DateTime startTime, DateTime endTime, int timeout = 30000)
        {
           return mHightClient.FindNumberTagMinValue(tag, startTime, endTime, timeout);
        }

        /// <summary>
        /// 计算平均值
        /// </summary>
        /// <param name="tag">变量的Id</param>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public double? FindNumberTagAvgValue(int tag, DateTime startTime, DateTime endTime, int timeout = 30000)
        {
            return mHightClient.FindNumberTagAvgValue(tag, startTime, endTime, timeout);
        }

        /// <summary>
        /// 修改历史数据
        /// </summary>
        /// <param name="id">变量ID</param>
        /// <param name="type">变量类型</param>
        /// <param name="user">操作用户</param>
        /// <param name="msg">操作备注</param>
        /// <param name="values">值的集合</param>
        /// <param name="timeout">超时</param>
        /// <returns></returns>
        public bool ModifyHisData(int id, Cdy.Tag.TagType type, string user, string msg, IEnumerable<TagHisValue<object>> values, int timeout = 30000)
        {
            return mHightClient.ModifyHisData(id, type, user, msg, values, timeout);
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="id">Id</param>
        /// <param name="user">用户名</param>
        /// <param name="msg">操作备注</param>
        /// <param name="stime">开始时间</param>
        /// <param name="etime">结束时间</param>
        /// <param name="timeout">超时</param>
        /// <returns></returns>
        public bool DeleteHisValue(int id, string user, string msg, DateTime stime, DateTime etime, int timeout = 60000)
        {

           return mHightClient.DeleteHisValue(id, user, msg, stime, etime, timeout);
        }
        #endregion

        #endregion

        #region Collector DirverAPI

        /// <summary>
        /// 数值变量值改变回调
        /// 当消费端设置变量时，会触发此回调
        /// </summary>
        /// <param name="callback"></param>
        public void SetValueChangeCallBackForCollector(DirectAccessDriver.ClientApi.DirectAccessClient.ProcessDataPushDelegate callback)
        {
            mDriverClient.ValueChanged=callback;
        }

        /// <summary>
        /// 设置数据库变更通知回调
        /// </summary>
        /// <param name="callback"></param>
        public void SetDatabaseChangedCallBackForCollector(DirectAccessDriver.ClientApi.DirectAccessClient.DatabaseChangedDelegate callback)
        {
            mDriverClient.DatabaseChanged=callback;
        }


        #region RealValue

        /// <summary>
        /// 带时间戳的设置实时、历史值
        /// </summary>
        /// <param name="values"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetTagRealAndHisValueWithTimerForCollector(List<Cdy.Tag.RealTagValueWithTimer> values, int timeout = 5000)
        {
            return mDriverClient.SetTagRealAndHisValueWithTimer(values, timeout);
        }


        /// <summary>
        /// 带时间戳的设置实时、历史值
        /// </summary>
        /// <param name="values">值集合</param>
        /// <param name="callback">结果回调</param>
        /// <param name="timeout">超时</param>
        /// <returns></returns>
        public void SetTagRealAndHisValueWithTimerForCollectorAsync(List<Cdy.Tag.RealTagValueWithTimer> values,Action<bool> callback, int timeout = 5000)
        {
            mDriverClient.SetTagRealAndHisValueWithTimerAsync(values,callback, timeout);
        }

        /// <summary>
        /// 带时间戳的设置实时、历史值
        /// 用于单向传输网管模式
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public bool SetTagRealAndHisValueWithTimer2ForCollector(List<Cdy.Tag.RealTagValueWithTimer> values)
        {
            return mDriverClient.SetTagRealAndHisValueWithTimer2(values);
        }

        /// <summary>
        /// 删除超时无效数据
        /// </summary>
        public void CheckAndRemoveTimeoutDataForCollector()
        {
            mDriverClient.CheckAndRemoveTimeoutData();
        }

        /// <summary>
        /// 采集端 设置一组变量的实时同时对于驱动记录类型的变量,记录到历史
        /// 对于历史,记录类型为驱动时起作用
        /// </summary>
        /// <param name="data"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetTagRealAndHisValueForCollector(DirectAccessDriver.ClientApi.RealDataBuffer data, int timeout = 5000)
        {
            return mDriverClient.SetTagRealAndHisValue(data, timeout);
        }





        /// <summary>
        /// 采集端 异步模式 设置一组变量的实时同时对于驱动记录类型的变量,记录到历史
        /// 对于历史,记录类型为驱动时起作用
        /// </summary>
        /// <param name="data">数值内存块</param>
        /// <param name="callback">结果回调</param>
        /// <param name="timeout">超时</param>
        /// <returns></returns>
        public void SetTagRealAndHisValueForCollectorAsync(DirectAccessDriver.ClientApi.RealDataBuffer data,Action<bool> callback, int timeout = 5000)
        {
            mDriverClient.SetTagRealAndHisValueAsync(data, callback,timeout);
        }

        /// <summary>
        /// 采集端 设置一组变量的实时同时对于驱动记录类型的变量,记录到历史
        /// 对于历史,记录类型为驱动时起作用
        /// 不需要等待服务器返回响应，不需要预先登录，每次请求均带着用户名、密码,用于数据单向传输
        /// </summary>
        /// <param name="data"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetTagRealAndHisValue2ForCollector(DirectAccessDriver.ClientApi.RealDataBuffer data)
        {
            return mDriverClient.SetTagRealAndHisValue2(data);
        }

        /// <summary>
        /// 采集端 设置一组变量的实时同时对于驱动记录类型的变量,记录到历史
        /// 对于历史,记录类型为驱动时起作用
        /// </summary>
        /// <param name="values"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetTagRealAndHisValueForCollector(List<Cdy.Tag.RealTagValue> values, int timeout = 5000)
        {
            return mDriverClient.SetTagRealAndHisValue(values, timeout);
        }


        /// <summary>
        /// 采集端 设置一组变量的实时同时对于驱动记录类型的变量,记录到历史
        /// 对于历史,记录类型为驱动时起作用
        /// </summary>
        /// <param name="values"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public void SetTagRealAndHisValueForCollectorAsync(List<Cdy.Tag.RealTagValue> values,Action<bool> callback, int timeout = 5000)
        {
            mDriverClient.SetTagRealAndHisValueAsync(values,callback, timeout);
        }

        /// <summary>
        /// 采集端 设置一组变量的实时值、时间和质量戳
        /// </summary>
        /// <param name="values"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetTagValueTimerAndQualityForCollector(List<Cdy.Tag.RealTagValueWithTimer> values, int timeout = 5000)
        {
            return mDriverClient.SetTagValueTimerAndQuality(values, timeout);
        }


        /// <summary>
        /// 采集端 设置一组变量的实时同时对于驱动记录类型的变量,记录到历史
        /// 对于历史,记录类型为驱动时起作用
        /// 用于数据单向传输
        /// </summary>
        /// <param name="values">ID，值类型，值，质量</param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetTagRealAndHisValue2ForCollector(List<Cdy.Tag.RealTagValue2> values)
        {
            return mDriverClient.SetTagRealAndHisValue2(values);
        }



        /// <summary>
        /// 采集端 设置一组变量的实时值和质量戳
        /// </summary>
        /// <param name="data"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetTagValueAndQualityForCollector(DirectAccessDriver.ClientApi.RealDataBuffer data, int timeout = 5000)
        {
           return mDriverClient.SetTagValueAndQuality(data, timeout);
        }


        /// <summary>
        /// 采集端 设置一组变量的实时值和质量戳
        /// 不需要等待服务器返回响应，不需要预先登录，每次请求均带着用户名、密码，用于单向传输的情况,用于数据单向传输
        /// </summary>
        /// <param name="data"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetTagValueAndQuality2ForCollector(DirectAccessDriver.ClientApi.RealDataBuffer data)
        {
            return mDriverClient.SetTagValueAndQuality(data);
        }



        /// <summary>
        /// 采集端 设置变量的实时
        /// </summary>
        /// <param name="values">ID，值类型，值，质量</param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetTagValueAndQualityForCollector(List<Cdy.Tag.RealTagValue> values, int timeout = 5000)
        {
            return mDriverClient.SetTagValueAndQuality(values, timeout);
        }


        /// <summary>
        /// 采集端 设置变量的实时和质量戳
        /// 用于数据单向传输
        /// </summary>
        /// <param name="values">ID，值类型，值，质量</param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetTagValueAndQuality2ForCollector(List<Cdy.Tag.RealTagValue2> values)
        {
            return mDriverClient.SetTagValueAndQuality2(values);
        }

        /// <summary>
        /// 采集端 订购指定变量的值改变通知回调
        /// 通常用户从业务端下发数据，采集端接受数据，并转发给硬件设备
        /// </summary>
        /// <param name="ids">Id集合</param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool AppendRegistorDataChangedCallBackForCollector(IEnumerable<int> ids, int timeout = 5000)
        {
            return mDriverClient.AppendRegistorDataChangedCallBack(ids, timeout);
        }

        /// <summary>
        /// 采集端 取消订购指定变量的值改变通知信息
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool UnRegistorDataChangedCallBackForCollector(IEnumerable<int> ids, int timeout = 5000)
        {
            return mDriverClient.UnRegistorDataChangedCallBack(ids,timeout);
        }

        /// <summary>
        /// 采集端 取消所有值改变订购信息
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool ResetRegistorDataChangedCallBackForCollector(int timeout = 5000)
        {
            return mDriverClient.ResetRegistorDataChangedCallBack();
        }

        #endregion

        /// <summary>
        /// 采集端 设置变量的一组历史值
        /// </summary>
        /// <param name="id">Id</param>
        /// <param name="type">值类型</param>
        /// <param name="values">值集合</param>
        /// <param name="timeout">超时</param>
        /// <returns></returns>
        public bool SetTagHisValueForCollector(int id, Cdy.Tag.TagType type, IEnumerable<Cdy.Tag.TagValue> values, int timeout = 5000)
        {
            return mDriverClient.SetTagHisValue(id, type, values, timeout);
        }

        /// <summary>
        /// 采集端 设置变量的一组历史值
        /// 用于数据的单向传输
        /// </summary>
        /// <param name="tagName">Id</param>
        /// <param name="type">值类型</param>
        /// <param name="values">值集合</param>
        /// <param name="timeout">超时</param>
        /// <returns></returns>
        public bool SetTagHisValue2ForCollector(string tagName, Cdy.Tag.TagType type, IEnumerable<Cdy.Tag.TagValue> values, int timeout = 5000)
        {
            return mDriverClient.SetTagHisValue2(tagName, type, values, timeout);
        }

        /// <summary>
        /// 采集端 设置变量的一组历史值
        /// </summary>
        /// <param name="id"></param>
        /// <param name="type"></param>
        /// <param name="data"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetTagHisValueForCollector(int id, Cdy.Tag.TagType type, DirectAccessDriver.ClientApi.HisDataBuffer data, int timeout = 5000)
        {
            return mDriverClient.SetTagHisValue(id , type, data, timeout);
        }


        /// <summary>
        /// 采集端 设置变量的一组历史值
        /// 用于数据的单向传输
        /// </summary>
        /// <param name="id"></param>
        /// <param name="type"></param>
        /// <param name="data"></param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetTagHisValue2ForCollector(string tagName, Cdy.Tag.TagType type, DirectAccessDriver.ClientApi.HisDataBuffer data, int timeout = 5000)
        {
            return mDriverClient.SetTagHisValue2(tagName , type, data, timeout);
        }

        /// <summary>
        /// 采集端 设置一组变量的历史值
        /// </summary>
        /// <param name="idvalues">ID，值集合</param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetMutiTagHisValueForCollector(Dictionary<int, IEnumerable<Cdy.Tag.TagValueAndType>> idvalues, int timeout = 5000)
        {
            return mDriverClient.SetMutiTagHisValue(idvalues, timeout);
        }


        /// <summary>
        /// 采集端 设置一组变量的历史值
        /// 用于数据的单向传输
        /// </summary>
        /// <param name="idvalues">ID，值集合</param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetMutiTagHisValue2ForCollector(Dictionary<string, IEnumerable<Cdy.Tag.TagValueAndType>> idvalues, int timeout = 5000)
        {
            return mDriverClient.SetMutiTagHisValue2(idvalues,timeout);
        }

        /// <summary>
        /// 采集端 设置一组变量的历史值
        /// </summary>
        /// <param name="idvalues">ID，值集合</param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetMutiTagHisValueForCollector(DirectAccessDriver.ClientApi.HisDataBuffer data, int valuecount, int timeout = 5000)
        {
            return mDriverClient.SetMutiTagHisValue(data, valuecount, timeout);
        }


        /// <summary>
        /// 采集端 设置一组变量的历史值
        /// 用于单项传输
        /// </summary>
        /// <param name="idvalues">ID，值集合</param>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public bool SetMutiTagHisValue2ForCollector(DirectAccessDriver.ClientApi.HisDataBuffer data, int valuecount, int timeout = 5000)
        {
            return mDriverClient.SetMutiTagHisValue2(data, valuecount, timeout);
        }


        /// <summary>
        /// 采集端 获取变量的ID
        /// </summary>
        /// <param name="tags">变量名称的集合</param>
        /// <param name="timeout"></param>
        /// <returns>ID 集合</returns>
        public List<int> QueryTagIdForCollector(IEnumerable<string> tags, int timeout = 5000)
        {
            return mDriverClient.QueryTagId(tags, timeout);
        }

        /// <summary>
        /// 采集端 通知使用的变量,用于单向传输时，同时网络中断，服务器知道哪些变量的质量戳设置成坏值
        /// </summary>
        /// <param name="tags">变量名称</param>
        /// <param name="timeout">超时</param>
        public void NotifyTagsForCollector(IEnumerable<string> tags, int timeout = 5000)
        {
             mDriverClient.NotifyTags(tags, timeout);
        }

        /// <summary>
        /// 采集端 该驱动对应的获取所有变量的ID，名称，类型
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns>ID、名称、类型集合</returns>
        public Dictionary<int, Tuple<string, byte>> QueryAllTagIdAndNamesForCollector(int timeout = 5000)
        {
            return mDriverClient.QueryAllTagIdAndNames(timeout);
        }

        /// <summary>
        /// 采集端 通过寄存器关键字查询变量
        /// </summary>
        /// <param name="filter">过滤条件</param>
        /// <param name="timeout">超时</param>
        /// <returns></returns>
        public Dictionary<int, Tuple<string, byte>> QueryTagIdAndNamesbyFilterForCollector(string filter, int timeout = 5000)
        {
           return mDriverClient.QueryTagIdAndNamesbyFilter(filter, timeout);
        }

        /// <summary>
        /// 采集端 获取所有历史记录类型为驱动的变量的ID
        /// </summary>
        /// <param name="timeout">超时</param>
        /// <returns>变量ID集合</returns>
        public List<int> GetDriverRecordTypeTagIdsForCollector(int timeout = 5000)
        {
           return mDriverClient.GetDriverRecordTypeTagIds(timeout);
        }

        /// <summary>
        /// 采集端 检查变量的记录类型是否为驱动自主更新类型
        /// </summary>
        /// <param name="ids">Id集合</param>
        /// <param name="timeout">超时</param>
        /// <returns></returns>
        public List<bool> CheckRecordTypeByTagIdForCollector(IEnumerable<int> ids, int timeout = 5000)
        {
            return mDriverClient.CheckRecordTypeByTagId(ids, timeout);
        }

        #endregion

        #region Develop WebAPi

        #region database



        /// <summary>
        /// 
        /// </summary>
        /// <param name="database"></param>
        /// <param name="desc"></param>
        /// <returns></returns>
        public bool NewDatabase(string database, string desc)
        {
            return mWebDevelopClient.NewDatabase(database, desc);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public List<DBDevelopClientWebApi.Database> QueryDatabase()
        {
           return mWebDevelopClient.QueryDatabase();
        }

        /// <summary>
        /// 启动
        /// </summary>
        /// <returns></returns>
        public bool Start(string database)
        {
           return mWebDevelopClient.Start(database);
        }

        /// <summary>
        /// 停止
        /// </summary>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool Stop(string database)
        {
            return mWebDevelopClient.Stop(database);
        }

        /// <summary>
        /// 热启动
        /// </summary>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool ReRun(string database)
        {
            return mWebDevelopClient.ReRun(database);
        }

        /// <summary>
        /// 数据库是否在运行
        /// </summary>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool IsDatabaseRunning(string database)
        {
           return mWebDevelopClient.IsDatabaseRunning(database);
        }

        /// <summary>
        /// 数据库是否变脏
        /// </summary>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool IsDatabaseDirty(string database)
        {
            return mWebDevelopClient.IsDatabaseDirty(database);
        }

        /// <summary>
        /// 获取变量组
        /// </summary>
        /// <param name="database"></param>
        /// <returns></returns>
        public List<DBDevelopClientWebApi.TagGroup> GetTagGroup(string database)
        {
            return mWebDevelopClient.GetTagGroup(database);
        }

        /// <summary>
        /// 获取所有变量
        /// </summary>
        /// <param name="database"></param>
        /// <returns></returns>
        public Dictionary<int, string> GetAllTagNames(string database)
        {
           return mWebDevelopClient.GetAllTagNames(database);
        }

        /// <summary>
        /// 获取某个组下的所有变量的名称
        /// </summary>
        /// <param name="database"></param>
        /// <param name="group"></param>
        /// <returns></returns>
        public Dictionary<int, string> GetAllTagNamesByGroup(string database, string group)
        {
           return mWebDevelopClient.GetAllTagNamesByGroup(database, group);
        }

        /// <summary>
        /// 获取某个组下的变量，采用分页模式
        /// </summary>
        /// <param name="database"></param>
        /// <param name="group"></param>
        /// <param name="pageIndex"></param>
        /// <param name="mFilter"></param>
        /// <returns></returns>
        public List<Tuple<Cdy.Tag.Tagbase, Cdy.Tag.HisTag>> GetTagByGroup(string database, string group, int pageIndex, out int pageCount, Dictionary<string, string> mFilter = null)
        {
            return mWebDevelopClient.GetTagByGroup(database, group, pageIndex, out pageCount, mFilter);
        }

        /// <summary>
        /// 获取某个组下的所有变量
        /// </summary>
        /// <param name="database"></param>
        /// <param name="group"></param>
        /// <param name="mFilter"></param>
        /// <returns></returns>
        public List<Tuple<Cdy.Tag.Tagbase, Cdy.Tag.HisTag>> GetAllTagByGroup(string database, string group,  Dictionary<string, string> mFilter = null)
        {
           return mWebDevelopClient.GetAllTagByGroup(database, group, mFilter);
        }


        /// <summary>
        /// 添加变量组
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public bool AddTagGroup(string name, string parentName, string database)
        {
            return mWebDevelopClient.AddTagGroup(name, parentName, database);
        }

        /// <summary>
        /// 更新变量组描述
        /// </summary>
        /// <param name="groupName"></param>
        /// <param name="desc"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool UpdateTagGroupDescription(string groupName, string desc, string database)
        {
           return mWebDevelopClient.UpdateTagGroupDescription(groupName, desc, database);
        }

        /// <summary>
        /// 删除变量组
        /// </summary>
        /// <param name="fullName"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool RemoveTagGroup(string fullName, string database)
        {
            return mWebDevelopClient.RemoveTagGroup(fullName, database);
        }

        /// <summary>
        /// 重命名变量组
        /// </summary>
        /// <param name="oldFullName"></param>
        /// <param name="newName"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool RenameTagGroup(string oldFullName, string newName, string database)
        {
            return mWebDevelopClient.RenameTagGroup(oldFullName, newName, database);
        }

        /// <summary>
        /// 移动变量组
        /// </summary>
        /// <param name="name"></param>
        /// <param name="oldParentName"></param>
        /// <param name="newParentName"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool MoveTagGroup(string name, string oldParentName, string newParentName, string database)
        {
            return mWebDevelopClient.MoveTagGroup(name, oldParentName, newParentName, database);
        }

        /// <summary>
        /// 删除变量
        /// </summary>
        /// <param name="tagIds"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool RemoveTags(List<int> tagIds, string database)
        {
           return mWebDevelopClient.RemoveTags(tagIds, database);
        }

        /// <summary>
        /// 删除变量
        /// </summary>
        /// <param name="tagId"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool RemoveTag(int tagId, string database)
        {
            return RemoveTags(new List<int>() { tagId }, database);
        }

        /// <summary>
        /// 添加变量
        /// </summary>
        /// <param name="realTag"></param>
        /// <param name="histag"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public int? AddTag(Cdy.Tag.Tagbase realTag, Cdy.Tag.HisTag histag, string database)
        {
            return mWebDevelopClient.AddTag(realTag, histag, database);
        }

        /// <summary>
        /// 添加变量
        /// </summary>
        /// <param name="mtags"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public List<int> AddTags(List<Tuple<Cdy.Tag.Tagbase, Cdy.Tag.HisTag>> mtags, string database)
        {
            return mWebDevelopClient.AddTags(mtags, database);
        }

        /// <summary>
        /// 更新变量历史配置
        /// </summary>
        /// <param name="histag"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool UpdateHisTag(Cdy.Tag.HisTag histag, string database)
        {
            return mWebDevelopClient.UpdateHisTag(histag, database);
        }

        /// <summary>
        /// 更新变量实时配置
        /// </summary>
        /// <param name="realtag"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool UpdateRealTag(Cdy.Tag.Tagbase realtag, string database)
        {
            return mWebDevelopClient.UpdateRealTag(realtag, database);
        }

        /// <summary>
        /// 导入
        /// </summary>
        /// <param name="realTag"></param>
        /// <param name="histag"></param>
        /// <param name="mode"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public int? Import(Cdy.Tag.Tagbase realTag, Cdy.Tag.HisTag histag, int mode, string database)
        {
            return mWebDevelopClient.Import(realTag, histag, mode, database);
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool Save(string database)
        {
           return mWebDevelopClient.Save(database);
        }

        /// <summary>
        /// 撤销更改
        /// </summary>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool Cancel(string database)
        {
            return mWebDevelopClient.Cancel(database);
        }

        /// <summary>
        /// 获取指定数据库的驱动参数配置
        /// </summary>
        /// <param name="database"></param>
        /// <returns></returns>
        public Dictionary<string, Dictionary<string, string>> GetDriverSetting(string database)
        {
            return mWebDevelopClient.GetDriverSetting(database);
        }

        /// <summary>
        /// 设置数据的驱动参数
        /// </summary>
        /// <param name="database"></param>
        /// <param name="settings"></param>
        /// <returns></returns>
        public bool UpdateDriverSetting(string database, Dictionary<string, Dictionary<string, string>> settings)
        {
            return mWebDevelopClient.UpdateDriverSetting(database, settings);
        }

        /// <summary>
        /// 获取代理接口API使能情况配置
        /// </summary>
        /// <param name="database"></param>
        /// <returns></returns>
        public DBDevelopClientWebApi.ProxyApiResponse GetDatabaseProxySetting(string database)
        {
            return mWebDevelopClient.GetDatabaseProxySetting(database);
        }

        /// <summary>
        /// 设置数据库代理接口API配置情况
        /// </summary>
        /// <param name="database"></param>
        /// <param name="enablewebapi"></param>
        /// <param name="enableopcua"></param>
        /// <param name="enablehighapi"></param>
        /// <param name="enablegrpc"></param>
        /// <returns></returns>
        public bool UpdateDatabaseProxySetting(string database, bool enablewebapi, bool enableopcua, bool enablehighapi, bool enablegrpc)
        {
            return mWebDevelopClient.UpdateDatabaseProxySetting(database, enablewebapi, enableopcua, enablehighapi, enablegrpc);
        }

        #endregion

        #region Database User

        /// <summary>
        /// 添加数据库用户组
        /// </summary>
        /// <param name="Name"></param>
        /// <param name="Parent"></param>
        /// <returns></returns>
        public bool AddDatabaseUserGroup(string Name, string Parent, string database)
        {
            return mWebDevelopClient.AddDatabaseUserGroup(Name, Parent, database);
        }

        /// <summary>
        /// 获取数据库用户组
        /// </summary>
        /// <param name="database"></param>
        /// <returns></returns>
        public List<DBDevelopClientWebApi.WebApiUserGroup> GetDatabaseUserGroup(string database)
        {
            return mWebDevelopClient.GetDatabaseUserGroup(database);
        }

        /// <summary>
        /// 移动数据库用户组
        /// </summary>
        /// <param name="name"></param>
        /// <param name="oldParentName"></param>
        /// <param name="newParentName"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool MoveDatabaseUserGroup(string name, string oldParentName, string newParentName, string database)
        {
            return mWebDevelopClient.MoveDatabaseUserGroup(name, oldParentName, newParentName, database);
        }

        /// <summary>
        /// 删除数据库用户组
        /// </summary>
        /// <param name="group"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool RemoveDatabaseUserGroup(string group, string database)
        {
            return mWebDevelopClient.RemoveDatabaseUserGroup(group, database);
        }

        /// <summary>
        /// 重名名数据库用户组
        /// </summary>
        /// <param name="newName"></param>
        /// <param name="oldFullName"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool RenameDatabaseUserGroup(string newName, string oldFullName, string database)
        {
            return mWebDevelopClient.RenameDatabaseUserGroup(newName, oldFullName, database);
        }

        /// <summary>
        /// 通过组获取数据库用户
        /// </summary>
        /// <param name="groupFullName"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public List<DBDevelopClientWebApi.WebApiUserInfoWithoutPassword> GetDatabaseUserByGroup(string groupFullName, string database)
        {
            return mWebDevelopClient.GetDatabaseUserByGroup(groupFullName, database);
        }

        /// <summary>
        /// 新建数据库用户
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="group"></param>
        /// <param name="permissions"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool NewDatabaseUser(string userName, string password, string group, List<string> permissions, string database)
        {
            return mWebDevelopClient.NewDatabaseUser(userName, password, group, permissions, database);
        }

        /// <summary>
        /// 更新数据库用户
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="group"></param>
        /// <param name="permissions"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool UpdateDatabaseUser(string userName, string password, string group, List<string> permissions, string database)
        {
            return mWebDevelopClient.UpdateDatabaseUser(userName, password, group, permissions, database);
        }

        /// <summary>
        /// 修改数据库用户
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool ModifyDatabaseUserPassword(string userName, string password, string database)
        {
           return mWebDevelopClient.ModifyDatabaseUserPassword(userName, password, database);
        }

        /// <summary>
        /// 删除数据库用户
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool RemoveDatabaseUser(string userName, string database)
        {
            return mWebDevelopClient.RemoveDatabaseUser(userName, database);
        }

        /// <summary>
        /// 新建数据库权限
        /// </summary>
        /// <param name="name"></param>
        /// <param name="desc"></param>
        /// <param name="enableWriter"></param>
        /// <param name="superPermission"></param>
        /// <param name="group"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool NewDatabasePermission(string name, string desc, bool enableWriter, bool superPermission, List<string> group, string database)
        {
            return mWebDevelopClient.NewDatabasePermission(name, desc, enableWriter, superPermission, group, database);
        }

        /// <summary>
        /// 删除数据库权限
        /// </summary>
        /// <param name="permission"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool RemoveDatabasePermission(string permission, string database)
        {
            return mWebDevelopClient.RemoveDatabasePermission(permission, database);
        }

        /// <summary>
        /// 删除数据库
        /// </summary>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool RemoveDatabase(string database)
        {
            return mWebDevelopClient.RemoveDatabase(database);
        }

        /// <summary>
        /// 更新数据库 权限
        /// </summary>
        /// <param name="name"></param>
        /// <param name="desc"></param>
        /// <param name="enableWriter"></param>
        /// <param name="superPermission"></param>
        /// <param name="group"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool UpdateDatabasePermission(string name, string desc, bool enableWriter, bool superPermission, List<string> group, string database)
        {
            return mWebDevelopClient.UpdateDatabasePermission(name, desc, enableWriter, superPermission, group, database);
        }

        /// <summary>
        /// 获取数据权限列表
        /// </summary>
        /// <param name="database"></param>
        /// <returns></returns>
        public List<UserPermission> GetDatabasePermission(string database)
        {
            return mWebDevelopClient.GetDatabasePermission(database);
        }

        #endregion

        #region System User

        /// <summary>
        /// 新建开发系统用户
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public bool NewUser(string username, string password)
        {
            return mWebDevelopClient.NewUser(username, password);
        }

        /// <summary>
        /// 重命名开发系统用户
        /// </summary>
        /// <param name="oldName"></param>
        /// <param name="newName"></param>
        /// <returns></returns>
        public bool ReNameUser(string oldName, string newName)
        {
            return mWebDevelopClient.ReNameUser(oldName, newName);
        }

        /// <summary>
        /// 修改开发系统用户密码
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="newpassword"></param>
        /// <returns></returns>
        public bool ModifyPassword(string userName, string password, string newpassword)
        {
            return mWebDevelopClient.ModifyPassword(userName, password, newpassword);
        }

        /// <summary>
        /// 更新开发系统用户
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="isAdmin"></param>
        /// <param name="newDatabasePerssion"></param>
        /// <param name="database"></param>
        /// <returns></returns>
        public bool UpdateUser(string userName, bool isAdmin, bool newDatabasePerssion, List<string> database)
        {
            return mWebDevelopClient.UpdateUser(userName, isAdmin, newDatabasePerssion, database);
        }

        ///// <summary>
        ///// 更新密码
        ///// </summary>
        ///// <param name="username"></param>
        ///// <param name="password"></param>
        ///// <returns></returns>
        //public bool UpdateUserPassword(string username, string password)
        //{
        //    if (string.IsNullOrEmpty(mLoginId))
        //    {
        //        LastErroMessage = "未登录";
        //        return false;
        //    }
        //    try
        //    {
        //        WebApiNewSystemUserRequest login = new WebApiNewSystemUserRequest() { UserName = username, Password = password, Id = mLoginId };
        //        string sval = Post("UpdateUserPassword", JsonConvert.SerializeObject(login));

        //        var result = JsonConvert.DeserializeObject<ResultResponse<bool>>(sval);
        //        if (result.HasErro)
        //        {
        //            LastErroMessage = result.ErroMsg;
        //            return false;
        //        }
        //        else
        //        {
        //            return result.Result;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        LastErroMessage = ex.Message;
        //        return false;
        //    }
        //}

        /// <summary>
        /// 获取开发系统用户
        /// </summary>
        /// <returns></returns>
        public List<DBDevelopClientWebApi.WebApiSystemUserItem> GetUsers()
        {
            return mWebDevelopClient.GetUsers();
        }

        /// <summary>
        /// 获取当前登录客户的配置信息
        /// </summary>
        /// <returns></returns>
        public WebApiSystemUserItem GetCurrentUserConfig()
        {
            return mWebDevelopClient.GetCurrentUserConfig();
        }

        /// <summary>
        /// 删除开发系统用户
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public bool RemoveUser(string userName)
        {
            return mWebDevelopClient.RemoveUser(userName);
        }

        /// <summary>
        /// 重置变量ID
        /// </summary>
        /// <param name="database"></param>
        /// <param name="tagids"></param>
        /// <param name="startId"></param>
        /// <returns></returns>
        public Dictionary<int, int> ResetTagIds(string database, List<int> tagids, int startId)
        {
            return mWebDevelopClient.ResetTagIds(database, tagids, startId);
        }

        #endregion

        #endregion

        protected void OnPropertyChanged(string name)
        {
            if(PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void Dispose()
        {
            mHightClient?.Dispose();
            mWebDevelopClient?.Dispose();
            mDriverClient?.Dispose();
            mHightClient=null;
            mWebDevelopClient = null;
            mHightClient = null;
        }
    }

    /// <summary>
    /// 
    /// </summary>
    public class ServerParameter
    {
        /// <summary>
        /// 
        /// </summary>
        public string Ip { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public int Port { get; set; } = -1;

        /// <summary>
        /// 
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public string Password { get; set; }
    }
}
